<?php
/**
 * @Author: king
 * @Date:   2019-05-04 16:46:12
 * @Last Modified by:   king
 * @Last Modified time: 2019-06-03 22:58:38
 */

namespace App\Models\Api;

use App\Models\Api\Base;
use App\Models\WxSetting;
use App\Exceptions\ApiException;
use Cache;
use Illuminate\Database\Eloquent\Model;

class Orders extends Base
{
    protected $table = 'orders';

    protected $dateFormat = 'U';
    public $guarded       = [];
    const CREATED_AT      = 'create_time';
    const UPDATED_AT      = 'update_time';
    public $timestamps    = true;

    private $active_start_time;
    private $active_end_time;

    const USER_UNPAIR_ORDER = ':order:unpaid';//用户所有未支付订单信息
    const USER_OIDS = ':order:oids';//用户所有订单缓存键名,根据订单类型
    const TIME_NUM = 'order:time_num';//一段时间的所有订单数量
    const REC_TIME_NUM = 'order:rec:time_num';//一段时间的生时矫正订单数量
    const FORTUNE_TIME_NUM = 'order:fortune:time_num:';//一段时间的运势订单数量(日运,月运,年运)
    const MAP_TIME_NUM = 'order:map:time_num';//一段时间的地图订单数量
    const VIDEO_TIME_NUM = 'order:video:time_num';//一段时间的课程订单数量
    const NUM_FOR_COURSE_ORDER = 'order:course:total_num';//课程购买人数缓存键名
    const NUM_FOR_FORTUNE_ORDER = 'fortune_orders_people_total';//运势购买人数缓存键名
    const FORTUNE_ORDER_BASE_NUM = 'fortune_order_base_num';//运势购买人数后台基数缓存键名
    const REC_ORDERS_PAY = ':order:rec:pay:';//用户当前已购买的生时矫正缓存键名,根据档案
    const FORTUNE_ORDERS_PAY = ':order:fortune:pay:';//用户当前已购买的日月年运势缓存键名,根据档案
    const MAP_ORDERS_PAY = ':order:map:pay:';//用户当前已购买的占星地图缓存键名,根据档案
    const VIDEO_ORDERS_PAY = ':order:video:pay:';//用户当前用户已购买的视频缓存键名
    const VIDEO_ORDERS_UNPAID = ':order:video:unpaid:';//用户当前用户未购买的视频缓存键名
    const ORDER_INFO_ID = ':order:info:';//用户订单详情缓存键名,根据订单id
    const CACHE_TIME = 86400 * 2;

    /**
     * 设置器,updatetime默认存入时间戳
     * @return int
     */
    public function setUpdateTimeAttr()
    {
        return time();
    }

    /**
     * 获取当前课程的所有购买人数,根据课程商品id
     * @param array $map
     *      gid int 商品id
     * @return bool|int|mixed|string
     */
    public function getCourseOrder($map = [])
    {
        $id = $map['gid'];

        $cache_name = self::NUM_FOR_COURSE_ORDER . $id;

        $videoOrderNum = false;
        if (intval($this->cache_on >= 1) && Cache::has($cache_name))
        {
            $videoOrderNum = Cache::get($cache_name);
        }
        // 运势订单id
        if ($videoOrderNum === false)
        {
            $where = ['gid' => $id, 'status' => 1];
            try
            {
                $videoOrderNum = $this
                    ->where($where)
                    ->groupBy('uid')
                    ->count('uid');
            }
            catch (\Exception $e)
            {
                $videoOrderNum = 0;// 课程购买人数默认为0
            }
            // 课程购买人数更新到缓存中
            if (intval($this->cache_on >= 1))
            {
                Cache::set($cache_name, $videoOrderNum, self::CACHE_TIME);
            }
        }
        return $videoOrderNum;
    }

    /**
     * 获取当前用户的所有订单id
     * @param array $map
     *      uid int 用户id
     *      type int 订单类型
     *      page int 分页页码
     * @return array|bool
     */
    public function getUidOrders($map = [])
    {
        $uid = (int)$map['uid'];
        $type = (int)$map['type'];
        $page = (int)$map['page'];
        // 定义默认查询条件
        $where = ['uid' => $uid, 'is_del' => 0];
        
        $query = $this->where($where)->orderBy('create_time', 'DESC')->select(['id', 'order_id', 'order_type']);
        
        switch ($type) {
            // 待支付
            case 1:
                $query->where('uid', $uid)
                    ->where('is_del', 0)
                    ->where('status', 0);
                break;
            // 进行中
            case 2:
                $query->where('uid', $uid)
                    ->where('is_del', 0)
                    ->where('status', 1);
               $query->whereIn('order_type', [1, 3, 4]);
                break;
            // 已完成
            case 3:
                $query->whereRaw("uid = $uid AND is_del =0 AND ((order_type = 1 AND status in (2,3,4,5)) OR (order_type in (2,5,6) AND status in (1,2,3)) OR (order_type in (3,4) AND status in (2,3,4)))");
                break;
        }

         $oids = false;

        if (intval($this->cache_on >= 1) && Cache::has('u' . $uid . ':' . $type . self::USER_OIDS))
        {
            $oids = Cache::get('u' . $uid . ':' . $type . self::USER_OIDS);
        }
        if ($oids === false)
        {
            try {
                
               $oids = $query->pluck('order_id')->toArray();
               //dd(\DB::getQueryLog());
               //dd($oids);
            // $oids = json_encode($oids, true);

                if (intval($this->cache_on >= 1))
                {
                    Cache::set('u' . $uid . ':' . $type . self::USER_OIDS, $oids, self::CACHE_TIME);
                }

            }
            catch (\Exception $e)
            {
                throw new ApiException('获取订单列表失败', 200, config('code.error'));
            }
        }
        

        $per_page = 50;// 当前订单每页显示数量
        
        // 统计有多少订单
        $total = count($oids);
        // 获取数据分页信息
        $data_list = getPaginatorData($total, $page, $per_page);

        // 获取分页后的订单id数组
        $all_course_id = array_slice($oids, $data_list['start'], $per_page);

        unset($data_list['start']);
        unset($data_list['end']);

        $rec_oids = [];
        $fortune_oids = [];
        $map_oids = [];
        $video_oids = [];
        $divi_question_oids = [];
        $astro_question_oids = [];
        $onlooker_oids = [];

        foreach ($all_course_id as $oid)
        {   
            $order_type = substr($oid, 1, 1);
            switch (true)
            {
                //生时矫正订单id
                case $order_type == 1:
                    $rec_oids[] = $oid;
                    break;
                //运势订单id
                case $order_type == 2:
                    $fortune_oids[] = $oid;
                    break;
                //占星地图订单id
                case $order_type == 3:
                    $map_oids[] = $oid;
                    break;
                //占星视频订单id
                case $order_type == 4:
                    $video_oids[] = $oid;
                    break;
                //平台占卜问答订单id
                case $order_type == 5:
                    $divi_question_oids[] = $oid;
                    break;
                //平台占星问答订单id
                case $order_type == 6:
                    $astro_question_oids[] = $oid;
                    break;
                //平台围观订单id
                case $order_type == 7:
                    $onlooker_oids[] = $oid;
                    break;
            }
        }


        // 生时矫正订单
        $rec_data = $this->get_orders_detail(['order_ids' => $rec_oids, 'order_type' => 1, 'uid' => $uid]);
        // 运势订单
        $fortune_data = $this->get_orders_detail(['order_ids' => $fortune_oids, 'order_type' => 2, 'uid' => $uid]);
        // 占星地图订单
        $map_data = $this->get_orders_detail(['order_ids' => $map_oids, 'order_type' => 3, 'uid' => $uid]);
        // 占星视频订单
        $video_data = $this->get_orders_detail(['order_ids' => $video_oids, 'order_type' => 4, 'uid' => $uid]);
        // 平台占卜问答订单
        $divi_question_data = $this->get_orders_detail(['order_ids' => $divi_question_oids, 'order_type' => 5, 'uid' => $uid]);
        // 平台占星订单
        $astro_question_data = $this->get_orders_detail(['order_ids' => $astro_question_oids, 'order_type' => 6, 'uid' => $uid]);
        // 平台围观订单
        $onlooker_data = $this->get_orders_detail(['order_ids' => $onlooker_oids, 'order_type' => 7, 'uid' => $uid]);

        $data_list['data'] = array_merge($rec_data, $fortune_data, $map_data, $video_data, $divi_question_data, $astro_question_data, $onlooker_data);
        // 将数据根据创建时间排序
        array_multisort(array_column($data_list['data'], 'create_time'), SORT_NUMERIC, SORT_DESC, $data_list['data']);

        return $data_list;
    }


    /**
     * 获取当前档案已支付的生时校正订单id
     * @param array $map
     * @return array|mixed|\PDOStatement|string|\think\Model
     */
    public function rec_orders($map = [])
    {
        $uid = $map['uid'];
        $rid = $map['rid'];

        $user_rec_pay_id = false;

        if (intval($this->cache_on >= 1) && Cache::has('u' . $uid . self::REC_ORDERS_PAY . $rid))
        {
            $user_rec_pay_id = Cache::get('u' . $uid . self::REC_ORDERS_PAY . $rid);
        }

        // 生时校正订单id
        if ($user_rec_pay_id === false)
        {
            try
            {
                $where  = ['order_type' => 1, 'uid' => $uid];
                $user_rec_pay_id = $this
                    ->select('order_id')
                    ->where($where)
                    ->whereIn('status', [1, 4, 5])
                    ->pluck('order_id')->toArray();
                if (intval($this->cache_on >= 1))
                    Cache::set('u' . $uid . self::REC_ORDERS_PAY . $rid, $user_rec_pay_id, self::CACHE_TIME);

            }
            catch (\Exception $e)
            {
                $user_rec_pay_id = [];// 文章列表默认为空
            }
        }
        $data = $this->get_orders_detail(['order_ids' => $user_rec_pay_id, 'order_type' => 1, 'uid' => $uid]);

        return $data;

    }

    /**
     * 获取当前档案已支付的运势订单,日,月,年分开
     * @param array $map
     * @return array|mixed|\PDOStatement|string|\think\Model
     */
    public function fortune_orders($map = [])
    {
        $uid = $map['uid'];
        $rid = $map['rid'];
        $type = $map['type'];

        $user_fortune_pay_id = false;

       /* if (intval($this->cache_on >= 1) && Cache::has('u' . $uid . self::FORTUNE_ORDERS_PAY . $type . ':' . $rid))
        {
            // 按当前类别获取已购买的订单ID缓存
            $user_fortune_pay_id = Cache::get('u' . $uid . self::FORTUNE_ORDERS_PAY . $type . ':' . $rid);
        }*/

        // 运势订单id
        if ($user_fortune_pay_id === false)
        {
            switch ($type)
            {
                 case 1:
                    $where = [
                        ['fr.rids', 'like', '%' . $rid . '%'],
                        'o.uid'        => $uid,
                        'o.status'     => 1,
                        'o.order_type' => 2,
                    ];
                    break;
                case 2:
                    $where = [
                        ['fr.rids', 'like', '%' . $rid . '%'],
                        'o.uid'        => $uid,
                        'o.order_type' => 3,
                    ];
                    break;
                case 3:
                    $where = [
                        ['fr.rids', 'like', '%' . $rid . '%'],
                        'o.uid'        => $uid,
                        'o.order_type' => 4,
                    ];
                    break;
                default:
                    $where = ' 1 > 2';
                    break;
            }

            try
            {
                $user_fortune_pay_id = $this->from('orders as o')
                    ->select('o.order_id')
                    ->join('fortune as  fr', 'o.fid', '=', 'fr.id', 'INNER')
                    ->where($where)
                    ->orderBy('o.create_time', 'DESC')
                    ->whereIn('o.status', [1, 4])
                    ->pluck('order_id')->toArray();
             
                if (intval($this->cache_on >= 1))
                    Cache::set('u' . $uid . self::FORTUNE_ORDERS_PAY . $type . ':' . $rid, $user_fortune_pay_id, self::CACHE_TIME);

            }
            catch (\Exception $e)
            {
                $user_fortune_pay_id = '';// 文章列表默认为空
            }
        }
        // 将订单id转为数组
       /* $user_fortune_pay_id = explode(',', $user_fortune_pay_id);

        // 去除数组最后一个元素
        array_pop($user_fortune_pay_id);*/
        $data = $this->get_orders_detail(['order_ids' => $user_fortune_pay_id, 'order_type' => 2, 'uid' => $uid]);

        return $data;
    }

    /**
     * 获取当前档案已支付的命格线订单
     * @param array $map
     * @return array|mixed|\PDOStatement|string|\think\Model
     */
    public function acg_map_orders($map = [])
    {
        $uid = $map['uid'];
        $rid = $map['rid'];

        $user_acg_pay_id = false;

        if (intval($this->cache_on >= 1) && Cache::has('u' . $uid . self::MAP_ORDERS_PAY . $rid))
        {
            $user_acg_pay_id = Cache::get('u' . $uid . self::MAP_ORDERS_PAY . $rid);
        }

        // 生时校正订单id
        if ($user_acg_pay_id === false)
        {
            try
            {
                $where = ['o.uid' => $uid, 'og.rid' => $rid, 'o.status' => 1, 'o.order_type' => 5];
                $user_acg_pay_id = $this
                    ->from('orders as o')
                    ->select('o.order_id')
                    ->join('orders_goods as og', 'o.id', '=', 'og.oid', 'INNER')
                    ->where($where)
                    ->orderBy('o.create_time', 'DESC')
                    ->pluck('order_id')->toArray();

            /*    $orders = json_decode(json_encode($orders, true), true);

                // 将订单id组成字符串
                if (!empty($orders)) foreach ($orders as $acl) $user_acg_pay_id .= $acl['id'] . ',';
                else $user_acg_pay_id = '';*/
                if (intval($this->cache_on >= 1))
                    Cache::set('u' . $uid . self::MAP_ORDERS_PAY . $rid, $user_acg_pay_id, self::CACHE_TIME);

            }
            catch (\Exception $e)
            {
                $user_acg_pay_id = '';// 文章列表默认为空
            }
        }

        $data = $this->get_orders_detail(['order_ids' => $user_acg_pay_id, 'order_type' => 3, 'uid' => $uid]);


        return $data;
    }

    /**
     * 获取当前用户已支付的视频订单
     * @param array $map
     * @return array|mixed|\PDOStatement|string|\think\Model
     */
    public function video_orders($map = [])
    {
        $uid = $map['uid'];

        $user_video_pay_id = false;

        if (intval($this->cache_on >= 1) && Cache::has('u' . $uid . self::VIDEO_ORDERS_PAY . $uid))
        {
            $user_video_pay_id = Cache::get('u' . $uid . self::VIDEO_ORDERS_PAY . $uid);
        }

        // 教学视频订单id
        if ($user_video_pay_id === false)
        {
            try
            {
                $where = ['uid' => $uid, 'status' => 1, 'order_type' => 6];
                $user_video_pay_id = $this
                    ->where($where)
                    ->orderBy('create_time', 'DESC')
                    ->get(['gid']);

                $user_video_pay_id = json_decode(json_encode($user_video_pay_id, true), true);
                if (intval($this->cache_on >= 1))
                    Cache::set('u' . $uid . self::VIDEO_ORDERS_PAY . $uid, $user_video_pay_id, self::CACHE_TIME);

            }
            catch (\Exception $e)
            {
                $user_video_pay_id = [];// 文章列表默认为空
            }
        }


        return $user_video_pay_id;
    }

    /**
     * 获取视频未支付的订单
     * @param array $map
     * @return array|bool|mixed|\PDOStatement|string|\think\Model
     */
    public function video_unpaid_orders($map = [])
    {
        $uid = $map['uid'];

        $user_video_pay_id = false;

        if (intval($this->cache_on >= 1) && Cache::has('u' . $uid . self::VIDEO_ORDERS_UNPAID . $uid))
        {
            $user_video_pay_id = Cache::get('u' . $uid . self::VIDEO_ORDERS_UNPAID . $uid);
        }

        //  教学视频订单id
        if ($user_video_pay_id === false)
        {
            try
            {
                $where = ['uid' => $uid, 'status' => 0, 'order_type' => 6];
                $user_video_pay_id = $this
                    ->select('id', 'gid', 'uid', 'order_id')
                    ->where($where)
                    ->orderBy('create_time', 'DESC')
                    ->get();

                $user_video_pay_id = json_decode(json_encode($user_video_pay_id, true), true);

                if (intval($this->cache_on >= 1))
                    Cache::set('u' . $uid . self::VIDEO_ORDERS_UNPAID . $uid, $user_video_pay_id, self::CACHE_TIME);

            }
            catch (\Exception $e)
            {
                $user_video_pay_id = [];// 文章列表默认为空
            }
        }


        return $user_video_pay_id;
    }

    /**
     * 获取订单详情信息
     * @param array $map
     * @return array
     */
    public function get_orders_detail($map = [])
    {
        $uid = $map['uid'];
        $order_ids = $map['order_ids'];
        $order_type = $map['order_type'];
        $data = [];

        // 根据当前页订单id获取所需的订单信息
        if (!empty($order_ids))
        {
            $ac_ids = [];
            $temp = [];

            // 从缓存订单内容,根据订单id
            foreach ($order_ids as $ac_id)
            {
                if (intval($this->cache_on >= 1) && Cache::has('u' . $uid . self::ORDER_INFO_ID . $ac_id))
                {
                    $temp[$ac_id] = Cache::get('u' . $uid . self::ORDER_INFO_ID . $ac_id);
                } else
                {
                    $temp[$ac_id] = false;
                }

                // 订单内容未缓存，等待从数据库中获取
                if ($temp[$ac_id] === false)
                {
                    $ac_ids[] = $ac_id;
                    unset($temp[$ac_id]);
                }
            }

            // 从数据库获取订单内容
            if (!empty($ac_ids))
            {
                $order_id = 'or.order_id';
                try
                {
                    switch($order_type)
                    { 

                        //生时矫正订单详情
                       case 1:
                            $field  = ['or.gid', 'g.name', 'g.or_prize', 'g.now_prize', 'g.expire_time', 'or.id as oid', 'or.status', 'or.order_id', 'or.uid', 'or.trade_type', 'or.total_amount', 'or.create_time', 'or.pay_time', 'or.return_time', 're.id as reid', 're.start_time', 're.end_time', 'or.account', 'or.order_type'];
                            $where['or.order_type'] = 1;
                            $orders = $this->from('orders as or')
                                ->join('goods as g', 'or.gid', '=', 'g.id', 'INNER')
                                ->join('rectification as  re', 'or.reid', '=', 're.id', 'INNER')
                                ->where($where)
                                ->whereIn($order_id, $ac_ids)
                                ->orderBy('or.create_time', 'DESC')
                                ->get($field);

                            break;
                        //运势订单详情
                        case 2:
                            $field  = ['or.gid', 'g.name', 'g.or_prize', 'g.now_prize', 'g.expire_time', 'or.id as oid', 'or.status', 'or.fid', 'or.order_id', 'or.uid', 'or.trade_type', 'or.total_amount', 'or.create_time', 'or.pay_time', 'or.update_time', 'or.return_time', 'or.extend', 'fr.extend', 'fr.time', 'fr.rids', 'fr.type', 'or.account', 'or.order_type'];
                            $orders = $this->from('orders as or')
                                ->join('goods as g', 'or.gid', '=', 'g.id', 'INNER')
                                ->join('fortune as fr', 'or.fid', '=', 'fr.id', 'INNER')
                                ->whereIn('or.order_type',[2, 3, 4])
                                ->whereIn($order_id, $ac_ids)
                                ->orderBy('or.create_time', 'DESC')
                                ->get($field);

                            break;
                        //占星地图订单详情
                        case 3:
                             $field  = ['og.gid', 'g.name', 'g.or_prize', 'g.now_prize', 'g.expire_time', 'g.discount', 'or.id as oid', 'or.status', 'or.order_id', 'or.uid', 'or.trade_type', 'or.total_amount', 'or.create_time', 'or.pay_time', 'or.return_time', 'og.rid', 'or.account', 'or.order_type'];
                            $where['or.order_type'] = 5;
                            $orders = $this->from('orders as or')
                                ->join('orders_goods as og', 'or.id', '=', 'og.oid', 'INNER')
                                ->join('goods as g', 'og.gid', '=', 'g.id', 'INNER')
                                ->where($where)
                                ->whereIn($order_id, $ac_ids)
                                ->orderBy('or.create_time', 'DESC')
                                ->get($field);
                            break;
                        //教学视频订单详情
                        case 4:
                            $field  = ['c.id as cid', 'c.title', 'or.gid', 'g.name', 'g.or_prize', 'g.now_prize', 'g.expire_time', 'or.id as oid', 'or.status', 'or.order_id', 'or.uid', 'or.trade_type', 'or.total_amount', 'or.create_time', 'or.pay_time', 'or.return_time', 'or.account', 'or.order_type'];
                            $where['or.order_type'] = 6;
                            $orders = $this->from('orders as or')
                                ->join('goods as g', 'or.gid', '=', 'g.id', 'INNER')
                                ->join('course as c', 'or.gid', '=', 'c.gid', 'INNER')
                                ->where($where)
                                ->whereIn($order_id, $ac_ids)
                                ->orderBy('or.create_time', 'DESC')
                                ->get($field);
                            break;
                        //平台占卜问答订单详情
                        case 5:
                            $field = ['or.gid','or.id as oid','or.status','or.order_id','or.uid','or.trade_type','or.total_amount','or.create_time','or.pay_time','or.return_time','or.account','or.order_type','p.title','p.counselor_price','d.planet','d.sign','d.house'];
                            $where['or.order_type'] = 7;
                            $orders = $this->from('orders as or')
                                ->join('counselor_problem as p', 'or.gid','=','p.id', 'INNER')
                                ->join('divination as d', 'p.bind_id','=','d.id', 'INNER')
                                ->where($where)
                                ->whereIn($order_id,$ac_ids)
                                ->orderBy('or.create_time', 'DESC')
                                ->get($field);
                            break;
                        //平台占星问答订单详情
                        case 6:
                            $field = ['or.gid','or.id as oid','or.status','or.order_id','or.uid','or.trade_type','or.total_amount','or.create_time','or.pay_time','or.return_time','or.account','or.order_type','p.title','p.counselor_price','p.bind_id'];
                            $where['or.order_type'] = 8;
                            $orders = $this->from('orders as or')
                                ->join('counselor_problem as p', 'or.gid','=','p.id', 'INNER')
                                ->where($where)
                                ->whereIn($order_id,$ac_ids)
                                ->orderBy('or.create_time', 'DESC')
                                ->get($field);
                            break;
                        //平台围观订单详情
                        case 7:
                            $field = ['or.gid','or.id as oid','or.status','or.order_id','or.uid','or.trade_type','or.total_amount','or.create_time','or.pay_time','or.return_time','or.account','or.order_type','p.title','p.counselor_price','c.nickname'];
                            $where['or.order_type'] = 9;
                            $orders = $this->from('orders as or')
                                ->join('counselor_problem as p', 'or.gid','=','p.id', 'INNER')
                                ->join('counselor_answer_onlooker as an', 'or.gid','=','p.id', 'INNER')
                                ->join('counselor_answer as a', 'or.gid','=','p.id', 'INNER')
                                ->join('counselor as c', 'or.gid','=','p.id', 'INNER')
                                ->where($where)
                                ->whereIn($order_id,$ac_ids)
                                ->orderBy('or.create_time', 'DESC')
                                ->get($field);
                            break;
                        default:
                            $orders = [];
                            break;
                    }

                    $orders = json_decode(json_encode($orders, true), true);
                }
                catch (\Exception $e)
                {
                    $orders = [];
                }

                if (!empty($orders))
                {
                    foreach ($orders as $c)
                    {
                        // 将订单内容缓存
                        if (intval($this->cache_on >= 1))
                        {
                            Cache::set('u' . $uid . self::ORDER_INFO_ID . $c['order_id'], $c, self::CACHE_TIME);
                        }
                        // 将数据库查出来的内容 写入到数组中为空的部分
                        $temp[] = $c;
                    }
                }
            }

            foreach ($temp as $k => $d)
            {
                if ($d)
                {
                    $data[] = $d;
                }
            }

        }
        return $data;
    }

    /**
     * 获取用户所有未支付订单,用于关闭订单
     * @param int $uid 用户id
     * @return array|bool
     */
    public function UserUnpairOrder($uid = 0)
    {
        $orders = false;

        if (intval($this->cache_on >= 1) && Cache::has('u' . $uid . self::USER_UNPAIR_ORDER))
        {
            $orders = Cache::get('u' . $uid . self::USER_UNPAIR_ORDER);
        }
        if ($orders === false)
        {
            //当前用户未删除待支付的订单
            $where = ['status' => 0, 'uid' => $uid, 'is_del' => 0, 'pay_time' => 0];
            try
            {
                // 获取当前用户的所有未支付订单
                $data = $this
                    ->select('id','order_id','create_time','pay_time')
                    ->where($where)
                    ->get();

                $orders = json_decode(json_encode($data, true), true);
            }
            catch (\Exception $e)
            {
                $orders = [];
            }
            if (intval($this->cache_on >= 1))
            {
                Cache::set('u' . $uid . self::USER_UNPAIR_ORDER, $orders, self::CACHE_TIME);
            }
        }
        return $orders;
    }

    /**
     * 删除单笔订单的缓存
     * @param array $map
     * @param array $data
     * @return bool
     */
    public function rm_cache($map = [], $data = [])
    {
        $uid = $map['uid'];
        $status = isset($map['status']) ? $map['status'] : 6; //0=>全部,1=>未支付,2=>进行中,3=>已完成(修改订单状态传入)
        $type = $map['type']; //1=>新增,2=>修改,3=>删除,4=>回调
        $order_id = $map['order_id'];

        if (intval($this->cache_on >= 1))
        {
            switch ($type)
            {
                case 1:
                    $this->RmOrderAdd($order_id, $uid);
                    break;
                case 2:
                    if ($status === 6)
                    {
                        //删除订单缓存
                        Cache::forget('u' . $uid . self::ORDER_INFO_ID . $order_id);
                    } else
                    {
                        $this->RmOrderIndex($order_id, $uid, $status);
                        //删除订单缓存
                        Cache::forget('u' . $uid . self::ORDER_INFO_ID . $order_id);
                    }
                    break;
                case 3:
                    $this->RmOrderIndex($order_id, $uid, $status);
                    //删除订单缓存
                    Cache::forget('u' . $uid . self::ORDER_INFO_ID . $order_id);
                    break;
                case 4:
                    $this->RmOrderIndex($order_id, $uid, $status);
                    //删除订单缓存
                    Cache::forget('u' . $uid . self::ORDER_INFO_ID . $order_id);
                    $this->RmOrderRid($order_id, $uid, $data);
                    break;
            }
        }

        return true;
    }

    /**
     * 更新订单列表缓存(新增时)
     * @param int $uid 用户id
     * @param string $order_id 新增的订单编号
     * @return bool
     */
    public function RmOrderAdd($order_id = '', $uid = 0)
    {  
        $a = Cache::get('u' . $uid . ':0' . self::USER_OIDS);
        
        $b = Cache::get('u' . $uid . ':1' . self::USER_OIDS);
        if ($a !== null)
        {
            array_unshift($a, $order_id);
            Cache::set('u' . $uid . ':0' . self::USER_OIDS, $a, self::CACHE_TIME);
        }
        if ($b !== null)
        {
            array_unshift($b, $order_id);
            Cache::set('u' . $uid . ':1' . self::USER_OIDS, $b, self::CACHE_TIME);
        }

        return true;
    }

    /**
     * 更新订单列表缓存,修改订单状态时,更新订单列表缓存(删除或修改订单时)
     * @param array $idArray 订单编号
     * @param int $uid 用户id
     * @return bool
     */
    public function RmOrderIndex($order_id = '', $uid = 0, $status = 6)
    {
        $a = Cache::get('u' . $uid . ':0' . self::USER_OIDS);
        $b = Cache::get('u' . $uid . ':1' . self::USER_OIDS);
        $c = Cache::get('u' . $uid . ':2' . self::USER_OIDS);
        $d = Cache::get('u' . $uid . ':3' . self::USER_OIDS);
        //更新未支付订单列表
        if ($b !== null)
        {
            $key2 = array_search($order_id, $b);
            if ($key2 !== null)
            {
                array_splice($b, $key2, 1);
                Cache::set('u' . $uid . ':1' . self::USER_OIDS, $b, self::CACHE_TIME);
            }
        }
        //更新进行中订单列表
        if ($c !== null)
        {
            $key3 = array_search($order_id, $c);
            if ($key3 !== null)
            {
                array_splice($c, $key3, 1);
                Cache::set('u' . $uid . ':2' . self::USER_OIDS, $c, self::CACHE_TIME);
            }
        }
        //更新已完成订单列表
        if ($d !== null)
        {
            $key4 = array_search($order_id, $d);
            if ($key4 !== null)
            {
                array_splice($d, $key4, 1);
                Cache::set('u' . $uid . ':3' . self::USER_OIDS, $d, self::CACHE_TIME);
            }
        }

        //更新新状态的订单缓存
        switch ($status)
        { 
            case 0:
                if ($a !== null)
                {
                    array_unshift($a, $order_id);
                    Cache::set('u' . $uid . ':0' . self::USER_OIDS, $a, self::CACHE_TIME);
                }
                break;
            case 1:
                if ($b !== null)
                {
                    array_unshift($b, $order_id);
                    Cache::set('u' . $uid . ':1' . self::USER_OIDS, $b, self::CACHE_TIME);
                }
                break;
            case 2:
                if ($c !== null)
                {
                    array_unshift($c, $order_id);
                    Cache::set('u' . $uid . ':2' . self::USER_OIDS, $c, self::CACHE_TIME);
                }
                break;
            case 3:
                if ($d !== null)
                {
                    array_unshift($d, $order_id);
                    Cache::set('u' . $uid . ':3' . self::USER_OIDS, $d, self::CACHE_TIME);
                }
                break;
             case 6:
                 $status = [0,1, 2, 3];//1=>未支付订单列表,2=>进行中订单列表,3=>已完成订单列表
                //更新列表缓存
                foreach ($status as $s)
                {
                    //删除订单列表
                    Cache::forget('u' . $uid . ':' . $s . self::USER_OIDS);
                }
        }

        return true;
    }

    /**
     * 更新档案已支付的订单缓存,支付订单时,更新档案已支付列表,增加已支付订单编号(订单回调时)
     * @param array $idArray
     * @param int $uid
     */
    public function RmOrderRid($order_id = '', $uid = 0, $data = [])
    {
        $num = substr($order_id, 1, 1);
        switch ($num)
        {
            //更新档案已支付的生时矫正订单
            case 1:
                $rec = Cache::get('u' . $uid . self::REC_ORDERS_PAY . $data['rid']);
                if ($rec !== null)
                {
                    array_unshift($rec, $order_id);
                    Cache::set('u' . $uid . self::REC_ORDERS_PAY . $data['rid'], $rec, self::CACHE_TIME);
                }
                break;
            //更新档案已支付的运势订单
            case 2:
                foreach ($data['rid'] as $rid)
                {
                    $fortune = Cache::get('u' . $uid . self::FORTUNE_ORDERS_PAY . $data['type'] . ':' . $rid);
                    \Log::info('支付回调订单缓存,打印档案:' . json_encode($fortune, true) . '数据:' . json_encode($data, true));
                    if ($fortune !== false)
                    {
                        array_unshift($fortune, $order_id);
                        Cache::set('u' . $uid . self::FORTUNE_ORDERS_PAY . $data['type'] . ':' . $rid, $fortune, self::CACHE_TIME);
                    }
                }
                //运势人数自增1
                Cache::increment('fortune_orders_people_total');
                break;
            //更新档案已支付的占星地图订单
            case 3:
                $where['or.order_id'] = $order_id;
                try
                {
                    $field = 'og.rid';
                    $data = $this->alias('or')
                        ->field($field)
                        ->join('wechat.app_orders_goods og', 'or.id=og.oid')
                        ->where($where)
                        ->findOrFail();
                }
                catch (\Exception $exception)
                {
                    $data = [];
                }
                if (!empty($data))
                {
                    // 当前档案占星地图订单(已支付)
                    $map = Cache::get('u' . $uid . self::MAP_ORDERS_PAY . $data['rid']);
                   \Log::info('支付回调订单缓存,打印档案:' . json_encode($map, true) . '数据:' . json_encode($data, true));
                    if ($map !== false)
                    {
                        array_unshift($map, $order_id);
                        Cache::set('u' . $uid . self::MAP_ORDERS_PAY . $data['rid'], $map, self::CACHE_TIME);
                    }
                    //当前档案已解锁和中奖的占星地图(用于占星地图首页的解锁判断)
                    Cache::forget('u' . $uid . ':recode_lines_' . $data['rid']);
                }
                break;
            //更新用户已支付的教学视频订单
            case 4:
                //删除用户已购买的教学视频订单缓存
                Cache::forget('u' . $uid . self::VIDEO_ORDERS_PAY . $uid);
                //删除用户所有未支付教学订单缓存
                Cache::forget('u' . $uid . self::VIDEO_ORDERS_UNPAID . $uid);
                Cache::increment('num:course:order');
                break;
        }

    }


   /**
 * 获取运势解锁人数(基数+购买人数)
 * @param array $map
 *      type int [1=>月运 ,2=>年运 ]
 * @return int
 */
public function fortune_base($map = [])
{
    $type = (int)$map['type'];
    $baseNum = false;

    // 获取运势基数 月运+年运
    if (intval($this->cache_on) >= 1)
    {
        $baseNum = Cache::get(self::FORTUNE_ORDER_BASE_NUM);
    }
    
    if ($baseNum === false)
    {
        try
        {
            // 根据key获取月运和年运的基数
            $baseNum = WxSetting::select('value', 'key')
                ->whereIn('key', ['month_base_num', 'year_base_num'])  // 假设key分别为 'month_base_num' 和 'year_base_num'
                ->get();

            // 将结果转换为一个数组，其中key为key字段，value为对应的基数值
            $baseNum = $baseNum->pluck('value', 'key')->toArray();

            // 如果没有从数据库获取到基数，设置默认值为0
            if (!isset($baseNum['month_base_num'])) {
                $baseNum['month_base_num'] = 0;  // 默认月运基数为0
            }
            if (!isset($baseNum['year_base_num'])) {
                $baseNum['year_base_num'] = 0;  // 默认年运基数为0
            }
        }
        catch (\Exception $e)
        {
            $baseNum = ['month_base_num' => 0, 'year_base_num' => 0];  // 默认月运和年运基数均为0
        }

        if (intval($this->cache_on) >= 1)
        {
            Cache::set(self::FORTUNE_ORDER_BASE_NUM, $baseNum, self::CACHE_TIME);
        }
    }

    // 根据传入的type选择月运或年运基数
    try
    {
        switch ($type)
        {
            case 1:  // 月运
                $baseNum = isset($baseNum['month_base_num']) ? $baseNum['month_base_num'] : 0;
                break;
            case 2:  // 年运
                $baseNum = isset($baseNum['year_base_num']) ? $baseNum['year_base_num'] : 0;
                break;
            default :
                $baseNum = 0;
                break;
        }
    }
    catch (\Exception $e)
    {
        $baseNum = 0;
    }

    // 统计订单购买人数
    $buyerNum = false;
    if (intval($this->cache_on) >= 1 && Cache::has(self::NUM_FOR_FORTUNE_ORDER))
    {
        $buyerNum = Cache::get(self::NUM_FOR_FORTUNE_ORDER);
    }

    if ($buyerNum === false)
    {
        try
        {
            // TODO 限制查询 订单为(月运+年运)订单
            $buyerNum = (new Orders())->whereIn('status', [1, 4])->groupBy('uid')->count('uid');
        }
        catch (\Exception $e)
        {
            $buyerNum = 0;
        }

        if (intval($this->cache_on) >= 1)
        {
            Cache::set(self::NUM_FOR_FORTUNE_ORDER, $buyerNum, self::CACHE_TIME);
        }
    }

    // 计算总人数
    $total = $buyerNum + $baseNum;

    return $total;
}

    /**
     * 在支付成功后,订单数自增 暂时作废
     * @param int $order_type 订单类型 1生时校正 21日运势 22月运势 23年运势 3占星地图 4占星视频 51占星问答 52占卜问答
     * @param int $fortune_type
     */
    public function inc_order_num($order_type = 0, $fortune_type = 0)
    {
        switch ($order_type)
        {
            case 1:
                Cache::increment(self::REC_TIME_NUM);
                break;
            case 2:
                Cache::increment(self::FORTUNE_TIME_NUM . $fortune_type);
                break;
            case 3:
                Cache::increment(self::MAP_TIME_NUM);
                break;
            case 4:
                Cache::increment(self::VIDEO_TIME_NUM);
                break;
            case 51:
                break;
            case 52:
                break;
        }
    }

    /**
     * 获取一段时间内的不同类型订单数量
     * @param int $order_type 订单类型
     * @return bool|int|mixed|string
     */
    public function getTimeTypeNum($order_type = 0)
    {
        $data = false;
        switch (true)
        {
            case $order_type == 1:
                $cache_name = self::REC_TIME_NUM;
                break;
            case in_array($order_type, [2, 3, 4]):
                $cache_name = self::FORTUNE_TIME_NUM . $order_type;
                break;
            case $order_type == 5:
                $cache_name = self::MAP_TIME_NUM;
                break;
            case $order_type == 6:
                $cache_name = self::VIDEO_TIME_NUM;
                break;
            default :
                $cache_name = '';
                break;
        }

        if (intval($this->cache_on >= 1) && Cache::has($cache_name))
        {
            $data = Cache::get($cache_name);
        }

        if ($data === false)
        {
            $where['status'] = 1;
            $where['pay_time'] = ['between', [strtotime(config('fortune.active_time')['start']), strtotime(config('fortune.active_time')['end'])]];
            $where['order_type'] = $order_type;
            try
            {
                $data = $this->where($where)->count('id');
                if (intval($this->cache_on >= 1))
                {
                    Cache::set($cache_name, $data, self::CACHE_TIME);
                }
            }
            catch (\Exception $e)
            {
                throw new ApiException("统计购买人数失败", 1);
                
            }
        }
        return $data;
    }

    /**
     * 获取一段时间内的所有订单数量
     */
    public function getTimeNum()
    {
        $data = false;

        if (intval($this->cache_on >= 1) && Cache::has(self::TIME_NUM))
        {
            $data = Cache::get(self::TIME_NUM);
        }

        if ($data === false)
        {
            $where['pay_time'] = ['between', [strtotime(config('fortune.active_time')['start']), strtotime(config('fortune.active_time')['end'])]];
            try
            {
                $data = $this->where($where)->count('id');
                if (intval($this->cache_on >= 1))
                {
                    Cache::set(self::TIME_NUM, $data, self::CACHE_TIME);
                }
            }
            catch (\Exception $e)
            {
               throw new ApiException("统计订单购买人数失败", 1);
               
            }
        }

        return $data;
    }
    
     /**
     * 获取当前用户的所有订单是否满足半年
     * @param array $map
     *      uid int 用户id
     *      type int 订单类型
     *      page int 分页页码
     * @return array|bool
     */
    public function getUnOrder($map = [])
    {
        $uid = (int)$map['uid'];
        $type = (int)$map['type'];
        $page = (int)$map['page'];
        // 定义默认查询条件
        $where = ['uid' => $uid, 'is_del' => 0];
        
        $query = $this->where($where)->orderBy('create_time', 'DESC')->select(['id', 'order_id', 'order_type']);
        
        switch ($type) {
            // 待支付
            case 1:
                $query->where('uid', $uid)
                    ->where('is_del', 0)
                   // ->where('status', 0)
                   ->whereRaw("DATEDIFF(NOW(), FROM_UNIXTIME(create_time)) <= 180");
                break;
        }

         $oids = false;

        if ($oids === false)
        {
            try {
                
               $oids = $query->get('order_id')->toArray();
               $orders = json_decode(json_encode($oids, true), true);
            }
            catch (\Exception $e)
            {
                throw new ApiException('获取订单列表失败', 200, config('code.error'));
            }
        }
        return $orders;
    }
}